#include "key.h"

static GPIO_InitTypeDef  GPIO_InitStructure;
static EXTI_InitTypeDef   EXTI_InitStructure;
static NVIC_InitTypeDef   NVIC_InitStructure;

/*函数指针初始化*/
volatile keyDonw_function_ptr key1Down_Handler = ptr_null_function;
volatile keyDonw_function_ptr key2Down_Handler = ptr_null_function;
volatile keyDonw_function_ptr key3Down_Handler = ptr_null_function;
volatile keyDonw_function_ptr key4Down_Handler = ptr_null_function;

// 初始化按键（外部中断）
void KEY_EXTI_Init(void)
{
	/* 1.打开外设时钟(根据需求再开启，节省功耗) */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);
		/* 使能系统配置控制器 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
	/* 2.配置4个按键的GPIO */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;			// GPIO引脚编号
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;		// 模式：输入模式
	//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		// 类型：推挽（输入模式无效）
	//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	// 输出速率：跟功耗相关（输入模式无效）
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	// 无上下拉
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;			// GPIO引脚编号
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	/* 3.连接外部中断线 */
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
	
	/* 4.配置外部中断线 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4;			// 外部中断线
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	// 中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  // 下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	/* 5.配置NVIC中断优先级（数值越大，优先级越低） */
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	// 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;			// 子优先级（响应优先级）
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	// 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;			// 子优先级（响应优先级）
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;	// 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;			// 子优先级（响应优先级）
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;	// 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;			// 子优先级（响应优先级）
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

// 中断服务函数（触发条件：按键1按下(PA0产生下降沿)）
void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0) != RESET)
	{
		key1Down_Handler();

		/* 清除标志位（便于下次产生中断） */
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
}

// 中断服务函数（触发条件：按键2按下(PE2产生下降沿)）
void EXTI2_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line2) != RESET)
	{
		key2Down_Handler();

		/* 清除标志位（便于下次产生中断） */
		EXTI_ClearITPendingBit(EXTI_Line2);
	}
}

// 中断服务函数（触发条件：按键3按下(PE3产生下降沿)
void EXTI3_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line3) != RESET)
	{
		key3Down_Handler();

		/* 清除标志位（便于下次产生中断） */
		EXTI_ClearITPendingBit(EXTI_Line3);
	}
}

// 中断服务函数（触发条件：按键4按下(PE4产生下降沿)）
void EXTI4_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line4) != RESET)
	{
		key4Down_Handler();

		/* 清除标志位（便于下次产生中断） */
		EXTI_ClearITPendingBit(EXTI_Line4);
	}
}

void ptr_null_function(void)
{
	
}
